<?php

declare(strict_types=1);
namespace Service\StorageService;


use Service\BaseService;
use Service\Code\Normal;
use App\Model\BbcModel\Inventory;
use App\Model\BbcModel\InventoryDetail;
use App\Model\BbcModel\InventoryDifference;
use App\Model\BbcModel\BManager;
use App\Model\BbcModel\Goods;
use App\Model\BbcModel\GoodsBatch;
use App\Model\BbcModel\PdaStockLoc;
use App\Model\BbcModel\MnStoreGoods;
use App\Model\BbcModel\StockLog;
use App\Model\BbcModel\Storage;
use App\Model\BbcModel\Mnuser;

class InventoryService extends BaseService
{
    public $type =[
        0=>'全场盘点',
        1=>'类别盘点',
        2=>'单品盘点',
        3=>'供应商盘点'
    ];
    /**
     * 获取pda盘点列表数据
     * @param int $cid
     * @param int $mn_sid
     * @param array $body
     * @return type
     */
    public function getLists(int $cid,int $mn_sid,array $body) {
        $page       = $body['page'] ?? 1;
        $limit      = $body['limit'] ??10;
        $where=[
            ['cid','=',$cid],
            ['df','=',0],
            ['mn_sid','=',$mn_sid],
            '_order_'=>['id'=>'desc']
        ];
        if ( isset($body['sn']) && !empty($body['sn']) ) {
            $where[]=['code','=',$body['sn']];
        }
        if ( !empty($body['starttime']) ) {
            $where[]=['cd','>=',strtotime($body['starttime'])];
        }
        if ( !empty($body['endtime']) ) {
            $where[]=['cd','<=',strtotime($body['endtime'])];
        }
        
        $basewhere=$where;
        if ( isset($body['new_status']) && $body['new_status']!=="" ) {
            $where[]=['new_status','=',$body['new_status']];
        }else{
            $where[]=['new_status','in',[0,1,2]];
        }
        $bmanager= BManager::instance()->lists(['mn_sid'=>$mn_sid]);
        $bmanagerMap= array_column($bmanager, null,'id');
        $list = Inventory::instance()->listPages($where, $limit, $page);
        $waitwhere= array_merge($basewhere, [['new_status','=',0]]);
        $doingwhere= array_merge($basewhere, [['new_status','=',1]]);
        $completewhere= array_merge($basewhere, [['new_status','=',2]]);
        $totalwhere=array_merge($basewhere, [['new_status','in',[0,1,2]]]);
        $total= Inventory::instance()->countNum($totalwhere);
        $waittotal= Inventory::instance()->countNum($waitwhere);
        $doingtotal= Inventory::instance()->countNum($doingwhere);
        $completetotal= Inventory::instance()->countNum($completewhere);
        foreach ($list as $key => $value) {
            $list[$key]['manager_name']=$bmanagerMap[$value['manager_id']]['name'];
            $list[$key]['type_name']= $this->type[$value['type']];
        }
        $data=[
            'list'=>$list,
            'total'=>$total,
            'wait_total'=>$waittotal,
            'doing_total'=>$doingtotal,
            'complete_total'=>$completetotal
        ];
        return Normal::returnCode(Normal::SUC,'成功',$data);
    }
    
    /**
     * 获取pda盘点详情商品搜索
     * @param int $cid
     * @param int $mn_sid
     * @param array $body
     * @return type
     */
    public function getSingleGoods(int $cid,int $mn_sid,array $body) {
        if(empty($body['inventory_id'])){
            return Normal::returnCode(Normal::FAIL,'盘点单id必传');
        }
        if(empty($body['search'])){
            return Normal::returnCode(Normal::FAIL,'搜索关键字必传');
        }
        $InventoryDetailTable = InventoryDetail::instance()->getTable();
        $query = InventoryDetail::instance()
        ->from("{$InventoryDetailTable} as i")
        ->leftjoin('ly_goods as g','g.id','=','i.goods_id')
//        ->leftjoin('ly_goods_batch as gb','gb.id','=','i.batch_id')
//        ->leftjoin('ly_pda_stock_loc as psl','gb.stock_loc','=','psl.id')
        ->where('i.inventory_id',$body['inventory_id']);
        $totalquery=InventoryDetail::instance()->where('inventory_id',$body['inventory_id']);
        $totalStockquantity=$totalquery->sum('stockquantity');
        $totalGoods=$totalquery->groupBy('goods_id')->count();
        $search = $body['search'];
        $query->where(function($query) use ($search)
        {
            $query->orWhere('g.skucode','like',"%{$search}%")
            ->orWhere('g.barcode','like',"%{$search}%")
            ->orWhere('g.name','like',"%{$search}%");
        });
        $alldetail=$query->select(['i.*'])->get()->toArray();        
        $detailMap=[];
        foreach ($alldetail as $key => $value) {
            $detailMap[$value['goods_id']][]=$value;
        }
        
        $batchids= array_column($alldetail, 'batch_id');
        $allBatch= GoodsBatch::instance()->whereIn('id', $batchids)->get()->toArray();
        $allBatchMap= array_column($allBatch, null,'id');
        $allStockLocids= array_column($allBatch, 'stock_loc');
        $allStockLoc= PdaStockLoc::instance()->where('mn_sid',$mn_sid)->whereIn('id',$allStockLocids)->get()->toArray();
        $allStockLocMap=empty($allStockLoc)?[]: array_column($allStockLoc, null,'id');
        $InventoryDetailList= $query->select([
            'i.goods_id',
            'g.barcode',
            'g.skucode',
            'g.name',
            'g.img',
            'g.is_bonded',
            'g.supplier_skucode'
        ])->groupBy('i.goods_id')->get()->toArray();
        foreach ($InventoryDetailList as $key => $value) {
            $InventoryDetailList[$key]['is_bonded_name']=Goods::$is_bonded[$value['is_bonded']];
            $detail=[];
            $sysquantity=0;
            $stockquantity=0;
            foreach ($detailMap[$value['goods_id']] as $k => $v) {
                $stock_loc=$allBatchMap[$v['batch_id']]['stock_loc'];
                $detail[]=[
                    'id'=>$v['id'],
                    'batch_id'=>$v['batch_id'],
                    'batch_no'=>$v['batch_no'],
                    'status'=>$v['status'],
                    'sysquantity'=>$v['sysquantity'],
                    'stockquantity'=>$v['stockquantity'],
                    'expired_date'=>$allBatchMap[$v['batch_id']]['expired_date']?date('Ymd',$allBatchMap[$v['batch_id']]['expired_date']):'默认效期',
                    'stock_loc'=>isset($allStockLocMap[$stock_loc]['code'])?$allStockLocMap[$stock_loc]['code']:'默认库位'
                ];
                $sysquantity=bcadd((string)$sysquantity,(string)$v['sysquantity']);
                $stockquantity=bcadd((string)$stockquantity,(string)$v['stockquantity']);
            }
            $InventoryDetailList[$key]['detail']=$detail;
            $InventoryDetailList[$key]['sysquantity']=$sysquantity;
            $InventoryDetailList[$key]['stockquantity']=$stockquantity;
        }
        $data=[
            'total_goods'=>$totalGoods,
            'total_stockquantity'=>$totalStockquantity,
            'list'=>$InventoryDetailList
        ];
        return Normal::returnCode(Normal::SUC, '成功', $data);
    }
    
    /**
     * pda盘点保存增加库存
     * @param int $cid
     * @param int $mn_sid
     * @param array $body
     * @return type
     */
    public function saveStock(int $cid,int $mn_sid,array $body) {
        if(empty($body['stockdata'])){
            return Normal::returnCode(Normal::FAIL, '库存信息必传');
        }
        if(empty($body['inventory_id'])){
            return Normal::returnCode(Normal::FAIL,'盘点单id必传');
        }
        $info=Inventory::instance()->info(['id'=>$body['inventory_id'],'df'=>0]);
        if(!$info){
            return Normal::returnCode(Normal::FAIL,'未找到盘点单');
        }
        $stockdata=$body['stockdata'];
        try
        {
            InventoryDetail::instance()->startTrans();
            foreach ($stockdata as $key => $value) {
                if(empty($value['inventory_detail_id'])){
                    InventoryDetail::instance()->rollback();
                    return Normal::returnCode(Normal::FAIL,'盘点单详情明细id必传');
                }
                if(!isset($value['stockquantity'])){
                    InventoryDetail::instance()->rollback();
                    return Normal::returnCode(Normal::FAIL,'仓库库存必传');
                }
                $inventory_detail= InventoryDetail::instance()->info(['id'=>$value['inventory_detail_id'],'inventory_id'=>$body['inventory_id']]);
                if(!$inventory_detail){
                    InventoryDetail::instance()->rollback();
                    return Normal::returnCode(Normal::FAIL,"盘点单详情明细id{$value['inventory_detail_id']}数据未找到");
                }
                $result= InventoryDetail::instance()->edit(['id'=>$value['inventory_detail_id']], ['stockquantity'=>$value['stockquantity'],'status'=>1,'md'=>time()]);
                if(!$result){
                    InventoryDetail::instance()->rollback();
                    return Normal::returnCode(Normal::FAIL,"盘点单详情明细id{$value['inventory_detail_id']}保存失败");
                }
            }
            if($info['status']==0){
                $inventoryresult=Inventory::instance()->edit(['id'=>$body['inventory_id']],['new_status'=>1,'md'=>time()]);
                if(!$inventoryresult){
                    InventoryDetail::instance()->rollback();
                   return Normal::returnCode(Normal::FAIL,"盘点状态变更失败");
                }
            }
            InventoryDetail::instance()->commit();
            return Normal::returnCode(Normal::SUC, '成功');
        } catch (\Exception $ex) {
            InventoryDetail::instance()->rollback();
            return Normal::returnCode(Normal::FAIL, '失败'.$ex->getMessage());
        }
        
    }
    /**
     * 生成盘点差异
     * @param int $cid
     * @param int $mn_sid
     * @param int $manager_id
     * @param array $body
     * @return type
     */
    public function adddiff(int $cid,int $mn_sid,int $manager_id,array $body) {
        if(empty($body['inventory_id'])){
            return Normal::returnCode(Normal::FAIL,'盘点单id必传');
        }
        $inventory_id=$body['inventory_id'];
        $inventory_info = Inventory::instance()->info(['id' => $inventory_id, 'mn_sid' =>$mn_sid,'df'=>0]);
        if (!$inventory_info) {
            return Normal::returnCode(Normal::FAIL,'盘点单不存在');
        }
        if ($inventory_info['status'] == 2) {
            return Normal::returnCode(Normal::FAIL,'盘点单已经完结');
        }elseif($inventory_info['status'] == 1){
            return Normal::returnCode(Normal::FAIL,'盘点单已经生成差异');
        }
        $c = Inventory::instance()->countNum([ 'status' => 1,'mn_sid'=>$mn_sid,'df'=>0]);
        if ($c) {
            return Normal::returnCode(Normal::FAIL,'已有单据生成差异,请先作废其他生成的差异单据,或者先执行已生产的差异！');
        }
        $listhas = InventoryDetail::instance()->countNum(['inventory_id' => $inventory_id, 'status' => 0]);
        if ($listhas>0) {
            return Normal::returnCode(Normal::FAIL,'商品还未盘点完结,请盘点完全部商品');
        }
        $list = InventoryDetail::instance()->lists(['inventory_id' => $inventory_id, 'status' => 1]);
        $time = time();
        foreach ($list as $key => $value) {
            $diff_info= InventoryDifference::instance()->info(['detail_id' => $value['id']]);
            if (!$diff_info) {
                InventoryDifference::instance()->add([
                    'cd' => $time,
                    'cid' => $value['cid'],
                    'sid' => $value['sid'],
                    'mn_sid' => $value['mn_sid'],
                    'manager_id' => $manager_id,
                    'inventory_id' => $value['inventory_id'],
                    'detail_id' => $value['id'],
                    'goods_id' => $value['goods_id'],
                    'batch_id' => $value['batch_id'],
                    'batch_no' => $value['batch_no'],
                    'status' => 0,
                ]);
            }else{
                InventoryDifference::instance()->edit(['id' => $diff_info['id']], ['cd' => $time, 'manager_id' => $manager_id]);
            }
        }
        Inventory::instance()->edit(['id' => $inventory_id], ['status' => 1,'new_status'=>2,'md'=>time()]);
        return Normal::returnCode(Normal::SUC, '成功');
    }
    
    /**
     * 作废盘点差异
     * @param int $cid
     * @param int $mn_sid
     * @param int $manager_id
     * @param array $body
     * @return type
     */
    public function cancelDiff(int $cid,int $mn_sid,int $manager_id,array $body) {
        if(empty($body['inventory_id'])){
            return Normal::returnCode(Normal::FAIL,'盘点单id必传');
        }
        $inventory_id=$body['inventory_id'];
        $inventory_info = Inventory::instance()->info(['id' => $inventory_id, 'mn_sid' =>$mn_sid,'df'=>0]);
        if (!$inventory_info) {
            return Normal::returnCode(Normal::FAIL,'盘点单不存在');
        }
        if ($inventory_info['status'] == 2) {
            return Normal::returnCode(Normal::FAIL,'盘点单已经完结');
        }
        $c = InventoryDifference::instance()->countNum(['inventory_id' => $inventory_id]);
        if (!$c) {
            return ['data' => '', 'code' => Normal::FAIL, 'message' => '请生成盘点差异！'];
        }
        Inventory::instance()->edit(['id' => $inventory_id], ['status' => 0,'new_status'=>1,'md'=>time()]);
        return Normal::returnCode(Normal::SUC, '成功');
    }
    
     /**
     * 删除盘点单
     * @param int $cid
     * @param int $mn_sid
     * @param int $manager_id
     * @param array $body
     * @return type
     */
    public function delInventory(int $cid,int $mn_sid,int $manager_id,array $body) {
        if(empty($body['inventory_id'])){
            return Normal::returnCode(Normal::FAIL,'盘点单id必传');
        }
        $inventory_id=$body['inventory_id'];
        $inventory_info = Inventory::instance()->info(['id' => $inventory_id, 'mn_sid' =>$mn_sid,'df'=>0]);
        if (!$inventory_info) {
            return Normal::returnCode(Normal::FAIL,'盘点单不存在');
        }
        if ($inventory_info['status'] == 2) {
            return Normal::returnCode(Normal::FAIL,'盘点单已经完结');
        }
        Inventory::instance()->edit(['id' => $inventory_id], ['df' => 1,'md'=>time()]);
        return Normal::returnCode(Normal::SUC, '成功');
    }
    
    /**
     * 获取差异
     * @param int $cid
     * @param int $mn_sid
     * @param array $body
     * @return type
     */
    public function getDiff(int $cid,int $mn_sid,array $body) {
        if(empty($body['inventory_id'])){
            return Normal::returnCode(Normal::FAIL,'盘点单id必传');
        }
        $inventoryInfo= Inventory::instance()->info(['id'=>$body['inventory_id'],'df'=>0]);
        if(empty($inventoryInfo)){
            return Normal::returnCode(Normal::FAIL,'未找到相关单据');
        }
        
        $page       = $body['page'] ?? 1;
        $limit      = $body['limit'] ??10;
        $InventoryDiffTable = InventoryDifference::instance()->getTable();
        $select=[
            'idiff.goods_id',
            'idiff.cd',
            'idiff.manager_id',
            'g.barcode',
            'g.skucode',
            'g.name',
            'g.img',
            'g.is_bonded',
            'g.supplier_skucode'
        ];
        $query = InventoryDifference::instance()
        ->from("{$InventoryDiffTable} as idiff")
        ->leftjoin('ly_goods as g','g.id','=','idiff.goods_id')
        ->where('idiff.inventory_id',$body['inventory_id'])->groupBy('idiff.goods_id');
        $pageInfo = $query->paginate((int)$limit,$select, 'page', (int)$page,true)->toArray();
        $list = $pageInfo['data'];
        $goodsIds= array_column($list, 'goods_id');
        $alldetail= InventoryDetail::instance()->where('inventory_id',$body['inventory_id'])->get()->toArray();
        $detailMap=[];
        $totalsysquantity=0;
        $totalstockquantity=0;
        foreach ($alldetail as $key => $value) {
            $detailMap[$value['goods_id']][]=$value;
            $totalsysquantity=bcadd((string)$totalsysquantity,(string)$value['sysquantity']);
            $totalstockquantity=bcadd((string)$totalstockquantity,(string)$value['stockquantity']);
        }
        $batchids= array_column($alldetail, 'batch_id');
        $allBatch= GoodsBatch::instance()->whereIn('id', $batchids)->get()->toArray();
        $allBatchMap= array_column($allBatch, null,'id');
        $allStockLocids= array_column($allBatch, 'stock_loc');
        $allStockLoc= PdaStockLoc::instance()->where('mn_sid',$mn_sid)->whereIn('id',$allStockLocids)->get()->toArray();
        $allStockLocMap=empty($allStockLoc)?[]: array_column($allStockLoc, null,'id');
        
        $inventoryDiffFirst=InventoryDifference::instance()->info(['inventory_id'=>$body['inventory_id']]);
        $manager= BManager::instance()->info(['id'=>$inventoryDiffFirst['manager_id']]);
        foreach ($list as $key => $value) {
            $list[$key]['is_bonded_name']=Goods::$is_bonded[$value['is_bonded']];
            $detail=[];
            $sysquantity=0;
            $stockquantity=0;
            foreach ($detailMap[$value['goods_id']] as $k => $v) {
                $stock_loc=$allBatchMap[$v['batch_id']]['stock_loc'];
                $detail[]=[
                    'id'=>$v['id'],
                    'batch_id'=>$v['batch_id'],
                    'batch_no'=>$v['batch_no'],
                    'sysquantity'=>$v['sysquantity'],
                    'stockquantity'=>$v['stockquantity'],
                    'expired_date'=>$allBatchMap[$v['batch_id']]['expired_date']?date('Ymd',$allBatchMap[$v['batch_id']]['expired_date']):'',
                    'stock_loc'=>isset($allStockLocMap[$stock_loc]['code'])?$allStockLocMap[$stock_loc]['code']:'',
                    'differ'=> bcsub((string)$v['stockquantity'],(string)$v['sysquantity'] )
                ];
                $sysquantity=bcadd((string)$sysquantity,(string)$v['sysquantity']);
                $stockquantity=bcadd((string)$stockquantity,(string)$v['stockquantity']);
            }
            $list[$key]['sysquantity']=$sysquantity;
            $list[$key]['stockquantity']=$stockquantity;
            $list[$key]['differ']= bcsub((string)$stockquantity,(string)$sysquantity );
            $list[$key]['detail']=$detail;
        }
        $differ=bcsub((string)$totalstockquantity,(string)$totalsysquantity );
        $differ_desc='盘平';
        if($differ<0){
            $differ_desc='盘亏';
        }else if($differ>0){
            $differ_desc='盘盈';
        }
        $data=[
            'cd'=> $inventoryDiffFirst['cd']?date("Y-m-d H:i:s",$inventoryDiffFirst['cd']):'',
            'manager'=>$manager['name'],
            'goods_quantity'=>$pageInfo['total'],
            'totalsysquantity'=>$totalsysquantity,
            'totalstockquantity'=>$totalstockquantity,
            'differ'=> $differ,
            'differ_desc'=>$differ_desc,
            'list'=>$list
        ];
        return Normal::returnCode(Normal::SUC, '成功',$data);
    }
    
    public function confirm($inventory_id,$manager_id=0,$review=0){
        $time = time();
        $inventory_info = Inventory::instance()->info(['id' => $inventory_id,'df'=>0]);
        if (!$inventory_info) {
            return Normal::returnCode(Normal::FAIL, '盘点单不存在');
        }
        if ($inventory_info['status'] == 2&&$review==0) {
            return Normal::returnCode(Normal::FAIL, '盘点单已完结');
        }
        if (($inventory_info['approvestatus'] != 0&&$review==1)||($inventory_info['approvestatus'] != 0&&$review==2)) {
            return Normal::returnCode(Normal::FAIL, '盘点单已审核');
        }
        if (($inventory_info['status'] != 2&&$review==1)||($inventory_info['status'] != 2&&$review==2)) {
            return Normal::returnCode(Normal::FAIL, '参数错误');
        }
        $cid = $inventory_info['cid'];
        $sid = $inventory_info['sid'];
        $mn_sid = $inventory_info['mn_sid'];
        $storage = Storage::instance()->info(['df' => 0, 'cid' => $cid, 'mn_sid' => $mn_sid, 'store_type' => 0]);
        if (!$storage) {
            return Normal::returnCode(Normal::FAIL, '仓库不存在');
        }
        $store_info = Mnuser::instance()->info(['id' => $mn_sid, 'status' => 1, 'new_store' => 1]);
        if (!$store_info) {
            return Normal::returnCode(Normal::FAIL, '店铺不存在');
        }
        if (!in_array($store_info['stock_share'], [1, 2])) {
            return Normal::returnCode(Normal::FAIL, '共享库存未知');
        }
        $delete_index_data = [];
        $list = InventoryDifference::instance()->lists(['inventory_id' => $inventory_id]);
        try
        {
            InventoryDetail::instance()->startTrans();
            if(($review==0&&$inventory_info['approvestatus']==1)||($review==1&&$inventory_info['approvestatus']==0&&$inventory_info['status']==2)){
                foreach ($list as $k => $v) {
                    //差异表
                    $result = InventoryDifference::instance()->edit(['id' => $v['id']], ['status' => 2, 'md' => $time]);
                    if (!$result) {
                        InventoryDetail::instance()->rollback();
                        return Normal::returnCode(Normal::FAIL, '执行失败11111');
                    }
                    //明细表
                    $detail_info = Inventorydetail::instance()->info(['id' => $v['detail_id']]);
                    if ($detail_info) {
                        $batch_id = $detail_info['batch_id'];
                        $goods_id = $detail_info['goods_id'];
                        $goods_info = Goods::instance()->info(['id' => $goods_id]);
                        $skucode = $goods_info['skucode'];
                        $sysquantity = $detail_info['sysquantity'];
                        $stockquantity = $detail_info['stockquantity'];
                        if (!$batch_id) {
                            InventoryDetail::instance()->rollback();
                            return Normal::returnCode(Normal::FAIL, '老数据，无批次，操作失败！');
                        }
//                        $cashgoodschange= CashGoodsChange::instance()->adddata([
//                            'cid'=>$cid,
//                            'mn_sid'=>$mn_sid,
//                            'goods_id'=>$goods_id
//                        ]);
//                        if(!$cashgoodschange){
//                            self::rollback();
//                            return ['data' => '', 'code' => Normal::FAIL, 'message' => '失败,变更记录'];
//                        }
                        //更新状态值
                        $result = Inventorydetail::instance()->edit(['id' => $detail_info['id']], ['status' => 2, 'md' => $time]);
                        if (!$result) {
                            InventoryDetail::instance()->rollback();
                            return Normal::returnCode(Normal::FAIL, '明细更改失败');
                        }
                        $cha_yi = $stockquantity - $sysquantity;
    //                    if($cha_yi!=0){
    //                        $result = Goodsbatch::instance()->edit(['id' => $batch_id], ['num' => $stockquantity, 'md' => $time]);
    //                        if (!$result) {
    //                            self::rollback();
    //                            return ['data' => '', 'code' => Normal::FAIL, 'message' => '更新批次失败！'];
    //                        }
    //                    }
                        $mn_goods_info = MnStoreGoods::instance()->info(['goods_id' => $goods_id, 'mn_sid' => $inventory_info['mn_sid']]);
                        if (!$mn_goods_info) {
                            InventoryDetail::instance()->rollback();
                            return Normal::returnCode(Normal::FAIL, 'sku【' . $skucode . '】商品不存在！');
                        }
                        //$cha_yi = $stockquantity - $sysquantity;
                        //盘盈
                        if ($cha_yi > 0) {
                            $result = Goodsbatch::instance()->where(['id' => $batch_id])->increment('num',$cha_yi);
                            if (!$result) {
                                InventoryDetail::instance()->rollback();
                                return Normal::returnCode(Normal::FAIL, '更新批次失败');
                            }
                            //写入日志
                            $result = StockLog::instance()->add([
                                'cid' => $inventory_info['cid'],
                                'mn_sid' => $inventory_info['mn_sid'],
                                'mnstoregoods_id' => $mn_goods_info['id'],
                                'goods_id' => $goods_id,
                                'batch_id' => $batch_id,
                                'quantity' => $cha_yi,//扣除批次库存
                                'type' => 5,
                                'bill_id' => $inventory_info['id'],
                                'bill_code' => $inventory_info['code'],
                                'status' => 1,
                                'remarks' => '盘点',
                                'cd'=>$time,
                                'manager_id'=>$manager_id??0
                            ]);
                            if (!$result) {
                                InventoryDetail::instance()->rollback();
                                return Normal::returnCode(Normal::FAIL,  'sku【' . $skucode . '】写入日志失败！');
                            }
                        }
                        if ($cha_yi < 0) {
                            $result = Goodsbatch::instance()->where(['id' => $batch_id])->decrement('num',abs($cha_yi));
                            if (!$result) {
                                InventoryDetail::instance()->rollback();
                                return Normal::returnCode(Normal::FAIL,  '更新批次失败');
                            }
                            $result = StockLog::instance()->add([
                                'cid' => $inventory_info['cid'],
                                'mn_sid' => $inventory_info['mn_sid'],
                                'mnstoregoods_id' => $mn_goods_info['id'],
                                'goods_id' => $goods_id,
                                'batch_id' => $batch_id,
                                'quantity' => abs($cha_yi),
                                'type' => 5,
                                'bill_id' => $inventory_info['id'],
                                'bill_code' => $inventory_info['code'],
                                'status' => 0,
                                'remarks' => '盘点',
                                'cd'=>$time,
                                'manager_id'=>$manager_id??0
                            ]);
                            if (!$result) {
                                InventoryDetail::instance()->rollback();
                                return Normal::returnCode(Normal::FAIL,  'sku【' . $skucode . '】写入日志失败！');
                            }
                        }
                        //可下单库存
                        $mn_num = $mn_goods_info['num'];
                        //线上实物库存
                        $mn_onlinequantity = $mn_goods_info['onlinequantity'];
                        //线下库存
                        $mn_quantity = $mn_goods_info['quantity'];
                        //共享库存
                        if ($store_info['stock_share'] == 1) {
                            //盘盈
                            if ($cha_yi > 0) {
                                $result = MnStoreGoods::instance()->where(['id' => $mn_goods_info['id']])->increment('num', $cha_yi);
                                if (!$result) {
                                    InventoryDetail::instance()->rollback();
                                    return Normal::returnCode(Normal::FAIL,  '更新库存失败');
                                }
                                $result = MnStoreGoods::instance()->where(['id' => $mn_goods_info['id']])->increment('quantity', $cha_yi);
                                if (!$result) {
                                    InventoryDetail::instance()->rollback();
                                    return Normal::returnCode(Normal::FAIL,  '更新库存失败');
                                }
                            }
                            //盘亏
                            if ($cha_yi < 0) {
                                $result = MnStoreGoods::instance()->where(['id' => $mn_goods_info['id']])->decrement('num', abs($cha_yi));
                                if (!$result) {
                                    InventoryDetail::instance()->rollback();
                                    return Normal::returnCode(Normal::FAIL,  '更新库存失败');
                                }
                                $result = MnStoreGoods::instance()->where(['id' => $mn_goods_info['id']])->decrement('quantity', abs($cha_yi));
                                if (!$result) {
                                    InventoryDetail::instance()->rollback();
                                    return Normal::returnCode(Normal::FAIL,  '更新库存失败');
                                }
                            }
                        }
                        //独立库存
                        if ($store_info['stock_share'] == 2) {
                            //盘盈
                            if ($cha_yi > 0) {
                                $result = MnStoreGoods::instance()->where(['id' => $mn_goods_info['id']])->increment('quantity', $cha_yi);
                                if (!$result) {
                                    InventoryDetail::instance()->rollback();
                                    return Normal::returnCode(Normal::FAIL,  '更新库存失败');
                                }
                            }
                            if ($cha_yi < 0) {
                                $abs_chayi = abs($cha_yi);
                                if ($abs_chayi <= $mn_quantity) {
                                    $result = MnStoreGoods::instance()->where(['id' => $mn_goods_info['id']])->decrement('quantity', $abs_chayi);
                                    if (!$result) {
                                        InventoryDetail::instance()->rollback();
                                        return Normal::returnCode(Normal::FAIL,  '更新库存失败');
                                    }
                                }

                                if ($abs_chayi > $mn_quantity) {//此处情况不存在,废逻辑
                                    //扣除上真实库存 并且扣除可用库存
                                    $kou = $abs_chayi - $mn_quantity;
                                    MnStoreGoods::instance()->edit(['id' => $mn_goods_info['id']], ['quantity' => 0]);
                                    $result = MnStoreGoods::instance()->where(['id' => $mn_goods_info['id']])->decrement('onlinequantity', $kou);
                                    if (!$result) {
                                        InventoryDetail::instance()->rollback();
                                        return Normal::returnCode(Normal::FAIL,  '更新库存失败');
                                    }
                                    $result = MnStoreGoods::instance()->where(['id' => $mn_goods_info['id']])->decrement('num', $kou);
                                    if (!$result) {
                                        InventoryDetail::instance()->rollback();
                                        return Normal::returnCode(Normal::FAIL,  '更新库存失败');
                                    }
                                    $goodsbatch= Goodsbatch::instance()->lists([['type','=',2],['mn_sid','=',$mn_sid],['goods_id','=',$goods_id],['num','>',0],'_order_'=>['id'=>'asc']]);
                                    if(!$goodsbatch){
                                        InventoryDetail::instance()->rollback();
                                        return Normal::returnCode(Normal::FAIL,  '未找到相关批次库存信息');
                                    }
                                    $nowquantity=$kou;
                                    $batch=[];            
                                    foreach ($goodsbatch as $key => $value) {
                                        $num=0;
                                        if($value['num']>=$nowquantity){
                                            $batchres= Goodsbatch::instance()->where(['id'=>$value['id']])->decrement('num',$nowquantity);
                                            $num=$nowquantity;
                                            $batch[]=['id'=>$value['id'],'quantity'=>$nowquantity,'batch_no'=>$value['batch_no']];
                                        }else{
                                            $batchres= Goodsbatch::instance()->where(['id'=>$value['id']])->decrement('num',$value['num']);
                                            $num=$value['num'];
                                            $batch[]=['id'=>$value['id'],'quantity'=>$value['num'],'batch_no'=>$value['batch_no']];
                                        }
                                        $nowquantity= bcsub((string)$nowquantity, (string)$num);
                                        if(!$batchres){
                                            InventoryDetail::instance()->rollback();
                                            return Normal::returnCode(Normal::FAIL,  '批次库存扣减失败');
                                        }
                                        StockLog::instance()->add([
                                            'cid'=>$cid,
                                            'mn_sid'=>$mn_sid,
                                            'mnstoregoods_id'=>$mn_goods_info['id'],
                                            'goods_id'=>$value['goods_id'],
                                            'batch_id'=>$value['id'],
                                            'quantity'=>$num,
                                            'type'=>5,
                                            'bill_id'=>$inventory_info['id'],
                                            'bill_code'=>$inventory_info['code'],
                                            'status'=>0,
                                            'remarks'=>'盘点',
                                            'cd'=>$time,
                                            'manager_id'=>$manager_id??0
                                        ]);
                                        if($nowquantity==0){
                                            break;
                                        }
                                    }

                                }
                            }
                        }
                    }
                }
            }
            $inventory_editdata=['status' => 2, 'md' => $time,'new_status'=>3];
            if($inventory_info['approvestatus']==0&&$inventory_info['status']==2){
                $inventory_editdata['approveuser']=$manager_id;
                $inventory_editdata['approvetime']=$time;
                $inventory_editdata['approvestatus']=$review;
            }
            $result = Inventory::instance()->edit(['id' => $inventory_id], $inventory_editdata);
            if (!$result) {
                InventoryDetail::instance()->rollback();
                return Normal::returnCode(Normal::FAIL,  '执行失败');
            }
            InventoryDetail::instance()->commit();
            return Normal::returnCode(Normal::SUC, '成功');
        } catch (\Exception $ex) {
            InventoryDetail::instance()->rollback();
            return Normal::returnCode(Normal::FAIL, '失败'.$ex->getMessage());
        }
    }
}
